#pragma once

#include "stream_server_rtsp.h"

#include <liveMedia/liveMedia.hh>
#include <BasicUsageEnvironment/BasicUsageEnvironment.hh>
#include <groupsock/GroupsockHelper.hh>

#include "media_stream.h"
#include "base_log.h"
#include "base_block_queue.h"

namespace El {
namespace StreamServer {

class StreamFramedSource : public FramedSource {
public:
    StreamFramedSource(UsageEnvironment &env, int32_t ch, int32_t type);
    ~StreamFramedSource();

private:
    static void deliverFrame0(void *clientData);
    void doGetNextFrame() override;

    void deliverFrame();
    void onFrame(const Media::MediaFramePtr &frame);
    void bufferExcessData(const uint8_t* data, size_t size);

private:
    int32_t fCh;
    int32_t fType;
    int32_t fHandle;
    std::unique_ptr<Base::BlockingQueue<Media::MediaFramePtr>> queue_{nullptr};
    std::vector<uint8_t> excessDataBuffer;  // New member to store excess data
    Media::MediaFramePtr currentFrame_;
};

class StreamServerMediaSubsession : public OnDemandServerMediaSubsession {
public:
    static StreamServerMediaSubsession *createNew(UsageEnvironment &env,
                                                  int32_t ch,
                                                  int32_t type,
                                                  bool reuseFirstSource);

private:
    StreamServerMediaSubsession(UsageEnvironment &env, int32_t ch, int32_t type, bool reuseFirstSource);

    virtual FramedSource *createNewStreamSource(unsigned clientSessionId, unsigned &estBitrate) override;

    virtual RTPSink *createNewRTPSink(Groupsock *rtpGroupsock,
                                      unsigned char rtpPayloadTypeIfDynamic,
                                      FramedSource *inputSource) override;

private:
    int32_t fCh;
    int32_t fType;
};

} // namespace StreamServer
} // namespace El